/*
 * @Author: your name
 * @Date: 2020-06-01 15:38:18
 * @LastEditTime: 2020-07-22 11:33:49
 * @LastEditors: Please set LastEditors
 * @Description: In User Settings Edit
 * @FilePath: \idiom_demo\assets\script\Game.ts
 */ 

import { SM } from "./SceneManager";
import { Grid } from "./game/Grid";
import { Idiom } from "./game/Idiom";
import { IdiomData } from "./game/IdiomData";
import { Level } from "./game/Level";
import { Res } from "./game/Res";


const {ccclass, property} = cc._decorator;

@ccclass
export class Game extends cc.Component {
    // 方块图片
    @property({     // 正常状态
        type: cc.SpriteFrame,
    })
    private word_normal: cc.SpriteFrame = null;
    @property({     // 正确
        type: cc.SpriteFrame,
    })
    private word_correct: cc.SpriteFrame = null;
    @property({     // 背景
        type: cc.SpriteFrame,
    })
    private word_tile: cc.SpriteFrame = null;
    @property({     // 选中
        type: cc.SpriteFrame,
    })
    private word_selected: cc.SpriteFrame = null;
    @property({     // 未中
        type: cc.SpriteFrame,
    })
    private word_unselected: cc.SpriteFrame = null;
    @property({     // 错误
        type: cc.SpriteFrame,
    })
    private word_wrong: cc.SpriteFrame = null;
    @property({     // 结束
        type: cc.SpriteFrame,
    })
    private word_finished: cc.SpriteFrame = null;

    @property(cc.Label)     // 关卡label
    private level_label: cc.Label = null;
    @property(cc.Prefab)    // 棋子
    private piece_prefab: cc.Prefab = null;
    @property(cc.Node)      // 棋盘
    private qipan: cc.Node = null;
    @property(cc.Node)      // 选词区
    private selectGroup: cc.Node = null;
    
    @property({             // 成语数据
        type: cc.JsonAsset,
    })
    private AllIdiomData: cc.JsonAsset = null;

    @property({             // 关卡数据1
        type: cc.JsonAsset,
    })
    private levelData_1: cc.JsonAsset = null;
    @property({             // 关卡数据2
        type: cc.JsonAsset,
    })
    private levelData_2: cc.JsonAsset = null;
    @property({             // 关卡数据3
        type: cc.JsonAsset,
    })
    private levelData_3: cc.JsonAsset = null;

    @property(cc.Boolean)   // debug模式
    private isDebug: boolean = false;

    private tiles = [];         // 棋子节点数组
    private selectWords = [];   // 选词数据数组
    private selectNode = [];    // 选词节点数组

    private currentSelectGrid: number = -1;
    private currentLevel: number = -1;
    
    @property(cc.Node)
    private res_node: cc.Node = null;
    private res: Res = null;

    private iData = [];

    // 开始界面
    @property(cc.Node)
    private menu_scene: cc.Node = null;

    onLoad () {
        // this.res = this.res_node.getComponent(Res);
        // // 初始化
        // this.init();
    }

    private init() {
        // 棋盘 9*9=81块    rows col
        for (let index = 0; index < 81; index++) {
            let node = cc.instantiate(this.piece_prefab);
            node.parent = this.qipan;
            let tile: Grid = node.getComponent(Grid);
            tile.gridId = index;
            if (!this.isDebug) {
                tile.hide();
            }
            this.tiles.push(tile);
        }
        // 更新布局
        this.qipan.getComponent(cc.Layout).updateLayout();

        // 初始化关卡数据
        this.initLevel(1);
    }

    private initLevel(currentLevel: number) {
        let ddd = null;
        switch(currentLevel) {
            case 1:
                ddd = this.levelData_1;
                this.currentLevel = currentLevel;
                break;
            case 2:
                ddd = this.levelData_2;
                this.currentLevel = currentLevel;
                break;
            case 3:
                ddd = this.levelData_3;
                this.currentLevel = currentLevel;
                break;
            default:
                ddd = this.levelData_1;
                this.currentLevel = currentLevel;
        }
        this.level_label.string = "第 " + this.currentLevel.toString() + " 关";
        // 初始化关卡
        let level: Level = new Level(this.AllIdiomData, ddd);
        let idiomArr = level.initLevelData();
        this.iData = idiomArr;

        // 遍历成语对象 
        for (let i = 0; i < idiomArr.length; i++) {
            let chars = idiomArr[i].data.chars;
            let grids = idiomArr[i].grids;
            // 分割拿到单独的字符
            let arr = chars.split("");
            for (let j = 0; j < grids.length; j++) {
                let gid = grids[j].id;
                let space = grids[j].space;

                this.tiles[gid].bg.node.active = true;
                this.tiles[gid].word.node.active = true;

                // 设置 格子信息
                this.tiles[gid].gridId = gid;
                this.tiles[gid].char = arr[j];
                this.tiles[gid].data = chars;
                this.tiles[gid].idioms.push(idiomArr[i]);

                // 判断是否为 去字 状态，如果是去字，那么就隐藏上面的word
                if (space) {
                    this.tiles[gid].isSpaceGrid = true;     // 空格子
                    if (!this.tiles[gid].isSelectMode) {    // 判断 该空是否为选词
                        this.tiles[gid].isSelectMode = true;
                        this.tiles[gid].bg.spriteFrame = this.word_tile;
                        // 添加点击事件
                        this.tiles[gid].addListener(this.onSpaceGridClick, this);
                        this.selectWords.push({"id": gid, "char": arr[j]});
                    }
                } else {
                    this.tiles[gid].word.string = arr[j];
                    this.tiles[gid].bg.spriteFrame = this.word_normal;
                }
            }
        }

        // 随机打乱selectWords数组
        this.selectWords.sort(() => {
            return Math.random() > 0.5 ? -1 : 1;
        });

        // 选词区
        this.initSelectGroup();

        // 寻找下一个空格子
        this.findNextSpaceGrid();
    }

    // 寻找下一个空格子
    private findNextSpaceGrid() {
        // 播放音效
        cc.audioEngine.play(this.res.nextAudioClicp, false, 1);

        for (let i = 0; i < this.tiles.length; i++) {
            if (this.tiles[i].isSelectMode && this.tiles[i].isUsed === false) {
                // 记录选中的格子位置
                this.currentSelectGrid = i;
                this.tiles[i].bg.spriteFrame = this.word_selected;
                return;
            }
        }

        // 如果没有下一个格子 就判断是否过关
        let flag = true;
        for (let sw = 0; sw < this.selectWords.length; sw++) {
            let id = this.selectWords[sw].id;
            if (this.tiles[id].isSuccess !== true) {
                flag = false;
            }
        }
        if (flag) {
            // 执行过关函数
            cc.log("过关");
            this.gameSuccess();
        }
    }

    // 空位置回调事件
    private onSpaceGridClick(e) {
        // 播放音效
        cc.audioEngine.play(this.res.clickAudioClicp, false, 1);

        let grid: Grid = e.target.getComponent(Grid);
        let gridId = grid.gridId;

        if (!this.tiles[this.currentSelectGrid].isUsed) {
            this.tiles[this.currentSelectGrid].bg.spriteFrame = this.word_tile;
        }
        
        this.currentSelectGrid = gridId;
        this.tiles[gridId].bg.spriteFrame = this.word_selected;

        // 标注空位置上已经有词  回退到选择区
        if (grid.isUsed) {
            let char = grid.word.string;
            this.tiles[gridId].isUsed = false;
            this.tiles[gridId].word.string = "";
            this.tiles[gridId].isSuccess = false;
            this.tiles[gridId].bg.spriteFrame = this.word_selected;
            this.currentSelectGrid = gridId;

            let currentid = grid.currentId;
            for (let i = 0; i < this.selectNode.length; i++) {
                if (this.selectNode[i].gridId === currentid) {
                    this.selectNode[i].node.getComponent(cc.Animation).play("show_word");
                }
            }
        }
    }

    // 选词 回调事件 ---> 判断与当前 选中位置 是否相符
    private onSelectGridClick(e) {
        // 播放音效
        cc.audioEngine.play(this.res.chooseAudioClicp, false, 1);

        let grid: Grid = e.target.getComponent(Grid);
        let gridId = grid.gridId;
        let char = grid.char;

        // 隐藏该选词 
        e.target.getComponent(cc.Animation).play("hide_word");
        if (this.tiles[this.currentSelectGrid].isUsed) {
            let char = this.tiles[this.currentSelectGrid].word.string;
            let nowId = this.tiles[this.currentSelectGrid].currentId;
            this.selectNode[nowId].node.active = true;
            this.tiles[this.currentSelectGrid].word.string = grid.char;
        } else {
            this.tiles[this.currentSelectGrid].word.string = grid.char;
            this.tiles[this.currentSelectGrid].isUsed = true;
            this.tiles[this.currentSelectGrid].bg.spriteFrame = this.word_finished;
            this.tiles[this.currentSelectGrid].currentId = gridId;
        }

        // 判断是否填词成功  通过比较字符的方式 gridId === this.currentSelectGrid
        if (char === this.tiles[this.currentSelectGrid].char) {
            // 记录该位置词语正确
            this.tiles[this.currentSelectGrid].isSuccess = true;
        }
        this.judgeSuccess(this.currentSelectGrid);
    }

    // 初始化选词区
    private initSelectGroup() {
        for (let s = 0; s < this.selectWords.length; s++) {
            let gid = this.selectWords[s].id;
            let char = this.selectWords[s].char;

            let node = cc.instantiate(this.piece_prefab);
            node.parent = this.selectGroup;
            let tile: Grid = node.getComponent(Grid);
            tile.gridId = gid;
            tile.char = char;
            tile.word.string = char;
            tile.addListener(this.onSelectGridClick, this);

            this.selectNode.push(tile);
        }
    }

    // 填词成功动画
    private fillGrid(grids, arr) {
        // 播放音效
        cc.audioEngine.play(this.res.rightAudioClicp, false, 1);

        for (let i = 0; i < grids.length; i++) {
            let id = grids[i].id;
            this.tiles[id].isSelectMode = false;
            // 每个字延迟动画
            setTimeout(() => {
                this.tiles[id].getComponent(cc.Animation).play("word_success");
            }, 100 * i);
        }

        for (let j = 0; j < arr.length; j++) {
            this.tiles[arr[j]].removeListener(null, this);
        }
    }

    // 填词错误动画
    private fillGridErr() {
        
    }

    // 判断词条成功
    private judgeSuccess(gridId: number) {
        let spaceArr = [];
        if (this.tiles[gridId].idioms.length > 0) {
            for (let i = 0; i < this.tiles[gridId].idioms.length; i++) {
                let idiom = this.tiles[gridId].idioms[i];
                let flag = true;
                spaceArr = [];
                // 遍历去字 位置
                for (let j in idiom.grids) {
                    let id = idiom.grids[j].id;
                    if (idiom.grids[j].space === true) {
                        spaceArr.push(id);
                    }
                }
                for (let s = 0; s < spaceArr.length; s++) {
                    if (this.tiles[spaceArr[s]].isSuccess !== true) {
                        flag = false;
                    }
                }

                if (flag) {
                    // 执行成功动画 
                    this.fillGrid(idiom.grids, spaceArr);
                }
            }

            // 找下一个 空位置
            this.findNextSpaceGrid();
        } else {
            cc.log("出错");
        }
    }

    // 过关
    private gameSuccess() {
        setTimeout(() => {
            // 播放音效
            cc.audioEngine.play(this.res.wowAudioClicp, false, 1);

            this.res.showWin(this.iData, this.currentLevel);
        }, 1000);
    }

    // 下一关按钮
    public onNextBtnClick(e, customEventData) {
        // 播放音效
        cc.audioEngine.play(this.res.clickAudioClicp, false, 1);

        // 清空选词区
        this.selectGroup.removeAllChildren();

        // 还原格子数据
        for (let i = 0; i < this.tiles.length; i++) {
            this.tiles[i].resetGrid();
        }

        this.selectWords = [];   // 选词数据数组
        this.selectNode = [];    // 选词节点数组
        this.currentSelectGrid = -1;
        this.iData = [];

        if (this.res) {
            this.res.hideWin();
        }
        
        cc.log(customEventData);
        let guanqia = null;
        if (customEventData === "reset") {
            guanqia = this.currentLevel;
        } else if (customEventData === "next") {
            guanqia = this.currentLevel + 1;
        } else {
            guanqia = this.currentLevel;
            cc.log("载入关卡出错！");
        }

        // 下一关
        this.initLevel(guanqia);
    }

    // 回主页按钮
    public onHomeBtnClick() {
        // 播放音效
        cc.audioEngine.play(this.res.clickAudioClicp, false, 1);
        
        //SM.enterMenuScene();
        cc.director.loadScene("game");
    }

    // 开始游戏
    public onStartBtnClick(e, c) {
        // 隐藏开始游戏界面
        this.menu_scene.active = false;

        // 初始化资源      
        this.res = this.res_node.getComponent(Res);
        // 初始化
        this.init();
    }

}